#include <iostream>
#include "node/node.h"
#include <Poco/StringTokenizer.h>
#include <Poco/TemporaryFile.h>

using Poco::StringTokenizer;
using Poco::TemporaryFile;
using namespace std;

Node node;

typedef void (*CLI)(string const&, istream &, ostream&, ostream&);

void put ( string const& input, istream & in, ostream& out, ostream& err ){
	out << "RunNode :: Going to send put to the next node" << endl;
	string filename;
	out << "filename: ";
	in >> filename;
	out << "RunNode :: Filename read " << filename <<  endl;
	File file = File(filename);
	node.put(filename, file);
}

void get ( string const& input, istream & in, ostream& out, ostream& err ){
	TemporaryFile file;
	file.keep();
	cout << " RunNode :: getting file into \"" << file.path() << "\"" << endl;
	node.get("testfile.txt", *((File*)&file));
}

void joinring ( string const& input, istream& in, ostream& out, ostream& err)
{
	cout << "RunNode :: Going to multicast a joinring" << endl;
	string ring;
	//in >> ring;

	node.joinRing("cecilia");
	cout << "RunNode :: JoinRing sent" << endl;
}

void join ( string const& input, istream & in, ostream& out, ostream& err ){
        cout << "Going to send join to slave" << endl;
        //StringTokenizer argv (input, " ", StringTokenizer::TOK_IGNORE_EMPTY);
        //cout << argv.count() << endl;
        bool error = false;
        string host;
        in >> host;

        UInt16 port;
       /*
        * if ( istream::failbit ) {
                error = true;
                cout << "Master::Error::Please enter a port" << endl;
        }
        else{
                cin >> port;
        } */

        in >> port;
        if( host.empty()){
                error = true;
                cout << "Master::Error::Please enter a host" << endl;
        }

        if(!error){
                node.join( host, port );
                cout << "RunMaster::Joined the slave "<< endl;
        }
}

void leave ( string const& input , istream& in, ostream& out, ostream& err )
{
	cout << "Going to send leave to slave" << endl;
	node.leave();
}

void info ( string const& input , istream& in, ostream& out, ostream& err )
{
	node.printNodeInfo();
}

int main( int argc, char ** argv){
	//Thread nodeThread;
	//nodeThread.start(node);

	map< string, CLI> commands;
	commands["join"] = &join;
	commands["put"] = &put;
	commands["get"] = &get;
	commands["leave"] = &leave;
	commands["joinring"] = &joinring;
	commands["info"] = &info;

	while( true ){
		string command;
		cout << "> ";
		cin >> command;

		if (command == "exit") {
			leave("", cin, cout, cerr);
			break;
		}

		StringTokenizer gilgamesj (command, " ", StringTokenizer::TOK_IGNORE_EMPTY);
		CLI cmd = commands[gilgamesj[0]];

		if(cmd != 0){
			cout<<"RunNode :: Reading Commands ::" << cmd << endl;
			cmd(command, cin, cout, cerr);
 			cout<<"RunNode :: Command executed" << endl;
		}
		cout<<"RunNode :: End of While loop" << endl;
	}
	cout<<"Node::Slave running"<<endl;
}
